const mongoose = require("mongoose");
const departmentModel = require("../../model/department");
const userModel = require("../../model/user");
const { flatToTree } = require("../../utils/treeHandle");
const { byKeysCreateNewObj } = require("../../utils/byKeysCreateNewObj");

// 获取部门列表
exports.getDepartmentModelList = async (req, res, next) => {
	const query = {};
	if (req.query.name) query.name = new RegExp(req.query.name, "i");
	if (req.query.status) query.status = req.query.status;

	try {
		const ret = await departmentModel.find(query).sort({ sort: 1 }).lean();
		const retTree = flatToTree({ dataArr: ret, isSort: false, didnFindPidIsInsertRoot: true });

		res.json({ code: 200, msg: "获取部门列表成功", data: retTree });
	} catch (error) {
		res.json({ code: 500, msg: "获取部门列表失败" });
	}
};

// 新增部门
exports.addDepartment = async (req, res, next) => {
	try {
		const ret = await departmentModel.create(req.body);
		res.json({ code: 200, msg: "新增部门成功", data: ret });
	} catch (error) {
		res.json({ code: 500, msg: "新增部门失败" });
	}
};

// 修改部门
exports.updateDepartment = async (req, res, next) => {
	try {
		const body = byKeysCreateNewObj({
			data: req.body,
			keys: ["name", "sort", "status", "pid"],
		});

		// 当前部门信息
		let departmentInfo;
		departmentInfo = await departmentModel.findOne({ _id: req.body._id });

		// 如果命中以下条件, 则需要使用该部门下的子节点
		let subordinates = [];
		if (body.status !== departmentInfo.status || req.body.pid) {
			subordinates = await departmentModel.aggregate([
				{
					$match: {
						_id: new mongoose.Types.ObjectId(req.body._id),
					},
				},
				{
					$graphLookup: {
						from: "departments",
						startWith: "$_id",
						connectFromField: "_id",
						connectToField: "pid",
						as: "children",
					},
				},
			]);
			if (subordinates.length > 0) subordinates = subordinates[0].children;
		}

		// 如果状态有变化, 则需要为该部门下的子节点进行更新.
		if (body.status !== departmentInfo.status) {
			// 先判断它的父部门是否启用, 如果没有启用, 则不允许修改状态.
			if (req.body.pid && req.body.status === "enable") {
				// 查询父级部门状态
				const parentDepartmentInfo = await departmentModel.findOne({ _id: req.body.pid });
				if (parentDepartmentInfo.status !== "enable") {
					return res.json({ code: 500, msg: "父部门状态处于禁用, 子部门无法修改状态!" });
				}
			}

			await departmentModel.updateMany(
				{
					_id: {
						$in: subordinates.map((item) => item._id),
					},
				},
				{ status: body.status }
			);
		}

		// 如果传入了父级id, 判断是否合法
		if (req.body.pid) {
			// 自己不能插入到自己
			if (req.body.pid === req.body._id) return res.json({ code: 500, msg: "自己不能插自己~" });

			// 它也不能插入到自己的子级中_查询当前编辑节点的子节点
			const subIds = subordinates.map((item) => item._id.toString());
			if (subIds.includes(req.body.pid)) return res.json({ code: 500, msg: "不能插入到自己的子节点中~" });
		}

		const ret = await departmentModel.updateOne({ _id: req.body._id }, body);
		res.json({ code: 200, msg: "修改部门成功", data: ret });
	} catch (e) {
		return res.json({ code: 500, msg: "修改部门失败" });
	}
};

// 删除部门
exports.deleteDepartment = async (req, res, next) => {
	// 检测
	try {
		const departmentInfo = await departmentModel.findOne({ _id: req.body.id });
		if (departmentInfo.key === "root") return res.json({ code: 500, msg: "不允许删除默认根部门" });
	} catch (e) {
		return res.json({ code: 500, msg: "删除部门失败" });
	}

	// 查询该部门下的子部门
	let subordinates = [];
	try {
		subordinates = await departmentModel.aggregate([
			{
				$match: { _id: new mongoose.Types.ObjectId(req.body.id) },
			},
			{
				$graphLookup: {
					from: "departments",
					startWith: "$_id",
					connectFromField: "_id",
					connectToField: "pid",
					as: "children",
				},
			},
		]);
		if (subordinates.length > 0) subordinates = subordinates[0].children.map((item) => item._id.toString());
	} catch (e) {
		return res.json({ code: 500, msg: "删除部门失败" });
	}

	try {
		await departmentModel.deleteMany({ _id: { $in: [...subordinates, req.body.id] } });
		res.json({ code: 200, msg: "删除部门成功" });
	} catch (e) {
		return res.json({ code: 500, msg: "删除部门失败" });
	}
};
